/*********************************************************************************
 *      Copyright:  (C) 2019 Wu Yujun<540726307@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  Sendtemper_client.c
 *    Description:  This file read ds18b20 get temperature and send info to server 
 *                 
 *        Version:  1.0.0(2019年01月17日)
 *         Author:  Wu Yujun <540726307@qq.com>
 *      ChangeLog:  1, Release initial version on "2019年01月17日 16时07分05秒"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <fcntl.h>
#include <libgen.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Sendtemper.h"
#define BUF_SIZE    512


int g_stop = 0 ;




void sig_handler(int SIG_NUM)
{
    if(SIG_NUM == SIGUSR1)
        g_stop = 1 ;
}
void print_usage(const char *program_name)
{
    printf("\n%s -- (2019.1.21)\n", program_name);
    printf(" Usage: %s -i <server_ip>/<server_hostname> -p <server_port>  [-h <server_use_help>]\n", program_name);
    printf("        -p --port       the port of the server you want to connect\n") ;
    printf("        -i --ip         the ip address or hostname of the server you want to connect\n") ;
    printf("        -h --help       the client file how to use\n");
    printf("        -d --daemon     the client progame running in backgruand\n");
    
    return ;
}


int main(int argc, char **argv)
{


    char                *sn = "WuYujun";
    char                *program_name ;
    char                now_time[BUF_SIZE] ;
    char                info_temp[BUF_SIZE] ;
    int                 daemon_run = 0 ;
    int                 port = 0 ;
    int                 opt = -1 ;
    char                *ip = NULL;
    struct hostent *    hostnp ;
    int                 no_ipport ;
    float               temper ;
    int                 sock_fd = -1;
    int                 log_fd = -1 ;
    struct sigaction    sa;


    program_name = basename(argv[0]) ;
    
    const char *short_opts = "i:n:p:hd";                    
    const struct option long_opts[] =   {  
        {"help", no_argument, NULL, 'h'},    
        {"ip", required_argument, NULL, 'i'},
        {"daemon", no_argument, NULL, 'd'},  
        { "port", required_argument, NULL, 'p'},  
        {0, 0, 0, 0} 
                                        };  
    while ((opt= getopt_long(argc, argv, short_opts, long_opts,NULL)) != -1) 
    {
        switch (opt) 
        {
            case 'i':
                    ip = optarg ;
                    break ;
            case 'p':
                    port = atoi(optarg) ;
                break ;
            case 'd':
                    daemon_run = 1 ;
                break ;
            case 'h':
                    print_usage(program_name) ;
                return 0 ;
        }
    }
    no_ipport = ( (!ip) || (!port) ) ;            //port or ip is NULL, no_ipprot = 1 ;

    if( no_ipport )
    {    
        print_usage(program_name);
        return 0;
    }

    /* connect server get host by name    */
    if ( inet_addr(ip)== INADDR_NONE )
    {
        if( (hostnp = gethostbyname(ip) ) == NULL )
        {
            printf("get host by name failure: %s\n", strerror(h_errno)) ;
            return -1 ;

        }
        printf("hostname %s\n", hostnp->h_name);
        ip = inet_ntoa( * (struct in_addr *)hostnp->h_addr );
        printf("addr:%s\n",ip) ;

    }

    /*  program running in backgruand    */
    if(daemon_run == 1)                      
    {
        printf("program %s running in backgrund\n", program_name);
        if( (log_fd = open("client.log", O_CREAT|O_RDWR, 0666)) < 0)
        {
            printf("open() failed:%s\n", strerror(errno)) ;
            return -2 ;
        }
        dup2(log_fd, STDOUT_FILENO) ;
        dup2(log_fd, STDERR_FILENO) ;
        daemon(1,1) ;
    }

    
    
    signal(SIGUSR1, sig_handler);
    /*  program stop till get sinal "SIGUSR1"   */
    sa.sa_handler = SIG_IGN;
    sigaction( SIGPIPE, &sa, 0 );
    /*   server close,client still write to server will  have sigpipe and kill process  */

    while(!g_stop)
    {
        if(ds18b20_get_temper(&temper)<0)
        {
            printf("ds18b20_get_temper() failed\n") ;
            goto cleanup ;
        }
        memset(now_time, 0, sizeof(now_time)) ;
        get_time(now_time) ;

        memset(info_temp, 0, sizeof(info_temp)) ;
        snprintf(info_temp, sizeof(info_temp), "%s/%s/%fC",sn ,now_time ,temper);
        printf("%s\n", info_temp) ;

        if(sock_fd < 0)
        {
            if( (sock_fd=connect_server(ip, port)) < 0 )
            {
                    printf("connect to server failure\n");
            }
            else
            {
                printf("connect suecessfully!\n") ;
            }
            
        }
        if(sock_fd >= 0)
        {
           if( write(sock_fd, info_temp, strlen(info_temp)) < 0 )
           {
                printf("write to server failed: %s\n", strerror(errno)) ;
                close(sock_fd) ;
                sock_fd = -1 ;
                continue ;
           }
           printf("Send information of temperature to server Ok\n") ;
        }
    
        sleep(30) ;
        if(daemon_run) //if running in backgrund, client.log should be limited
        {
                log_roll_back(log_fd) ;
        }
    }


    printf("Program exit\n") ;


cleanup:
        close(log_fd) ;
        close(sock_fd) ;
        return -3 ;
}
